#include "hi_ext_util.h"
#include "plug_mqtt_analysis.h"
#include "plug_mqtt.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */

typedef enum {
    REGISTER0 = 0,
    RT_VIDEO,
    RT_TALK,
}topicid;

typedef struct {
    HI_S8* topicName;
    topicid topid;
}TOPICLIST;

static TOPICLIST topicList[] = {
    {"register",REGISTER0}, //0x20->设备注册,register是一个关键字不能直接使用
    {"rt_video",RT_VIDEO},  //0x31->实时查看
    {"rt_talk",RT_TALK},    // 实时对讲
};
//解析topicName
static HI_S8* searchLastTopicName(HI_S8* topicName, HI_CHAR pt)
{
    HI_S32 i = strlen(topicName);
    HI_S8 *topicName0 = topicName;
    for(;i > 0;i--)
        if(pt == topicName[i]){
            break;
        }
    topicName0 = topicName+i+1;
    LOGD("the last topic name is:%s\n",topicName0);
    return topicName0;
}

/*
解析payloadptr，index为payloadptr的第几部分数据,
pazOutString为存放解析结果字符数组指针，
s32MaxOutLen为字符数组的长度
例：searchPayloadptr("0001/2/3.2/45.6",'/',0)，
返回0001；若将第三个参数0改为1，则返回2
bEnd:是否获取从/之后的所有字符串（包含/）
*/
static HI_S32 MQTT_SearchPayloadInfo(HI_CHAR* pazInString,
    HI_CHAR split, HI_S32 s32Index, HI_CHAR *pazOutString, HI_S32 s32MaxOutLen, HI_BOOL bEnd)
{
    HI_APPCOMM_CHECK_POINTER(pazInString, HI_FAILURE);
    HI_APPCOMM_CHECK_POINTER(pazOutString, HI_FAILURE);
    HI_S32 s32Idx = 0;
    HI_CHAR* pTmpString = HI_NULL;
    HI_CHAR* pThirdString = HI_NULL;
    HI_S32 s32StringLen = 0;
    
    pTmpString = pazInString;
    for (s32Idx = 0;s32Idx < s32Index; s32Idx++)
    {
        
        pTmpString = strchr(pTmpString, split);
        if ((HI_NULL == pTmpString) || (strlen(pTmpString) <= 1))
        {
            return HI_FAILURE;
        }
        pTmpString = pTmpString + 1;
    }
    
    pThirdString = strchr(pTmpString, split);
    if ((HI_NULL == pThirdString) || (HI_TRUE == bEnd))
    {
        snprintf(pazOutString, s32MaxOutLen, "%s", pTmpString);
    }
    else
    {
        s32StringLen = pThirdString - pTmpString;
        s32StringLen = (s32StringLen > s32MaxOutLen) ? s32MaxOutLen : s32StringLen;
        memcpy(pazOutString, pTmpString, s32StringLen);
    }
    
    return HI_SUCCESS;
}

/*解析payload数据并进行对应的业务处理*/
HI_S32 PLUG_MQTT_Analysis(HI_U8 *payloadptr, MQTTClient_message *message, HI_S8 *topicName)
{
    HI_S32 s32Ret,idx,argd;
    HI_CHAR *argb[10];
    PLUG_COMMON_DEV_INFO_S stInfo = {0};

    static PLUG_COMMON_DEV_INFO_S s_stDevInfo = {0};
    
    for (HI_S32 i = 0; i < sizeof(argb)/sizeof(HI_CHAR*); i++)
    {
        argb[i] = (HI_CHAR*)"\0";
    }
    
    HI_S8 *topicname = topicName;
    
    s32Ret = PLUG_COMMON_GetDeviceInfo(&stInfo);
    if (HI_SUCCESS != s32Ret)
    {
        LOGE("PLUG_COMMON_GetDeviceInfo error!\n");
    }
    
    //strtol(const char * nptr, char **endptr, int base)字符串转十六进制
    
    //1.获取topicName的最后一个主题,通过遍历topicName的最后一个字段来判断是哪一个主题
    HI_S8* topic = searchLastTopicName(topicname,'/');

    //2.计算需要遍历的所有topicName数量
    HI_U32 topnum =  sizeof(topicList)/sizeof(TOPICLIST);

    //3.解析payload的内容
    HI_CHAR payloadptr0[64] = {0};
    HI_CHAR payloadptr1[64] = {0};
    HI_S32 set = HI_SUCCESS;

    set = MQTT_SearchPayloadInfo(payloadptr, '/', 0, payloadptr0, sizeof(payloadptr0), HI_FALSE);
    if(set != HI_SUCCESS){
        LOGE("payloadptr0 analysis error!\n");
    }
    LOGD("payloadptr0 is %s  \n",payloadptr0);
    
    set = MQTT_SearchPayloadInfo(payloadptr, '/', 1, payloadptr1, sizeof(payloadptr1), HI_FALSE);
    if(set != HI_SUCCESS)
    {
        LOGE("payloadptr1 analysis error!\n");
    }
    
    LOGD("payloadptr1 is %s  \n",payloadptr1);
    //4.进一步遍历payload的内容
    for(idx = 0; idx < topnum; idx++){
        if(strcmp(topic, (HI_S8*)topicList[idx].topicName) == 0){
            if(message->payloadlen == 0)
                break;
            switch(topicList[idx].topid){/*匹配对应的topic*/
                /* 设备ID（是否成功） (eg:000001/0) */
                case REGISTER0:
                    /* 判断设备ID是否对应 */
                    if(strcmp(payloadptr0, stInfo.azDeviceId) == 0)
                    {
                        switch(atoi(payloadptr1))
                        {
                            case 0://0x00 设备注册成功
                                LOGI("Type:0 the dev register successfully!\n");
                                set = PLUG_COMM_CreateMqttHeartThread();
                                if(set != HI_SUCCESS){
                                    LOGE("PLUG_COMM_CreateMqttHeartThread failed!\n");
                                }
                                break;
                            case 1://0x01 设备重复注册
                                LOGI("Type:1  the dev has been register!\n");
                                set = PLUG_COMM_CreateMqttHeartThread();
                                if(set != HI_SUCCESS){
                                    LOGE("PLUG_COMM_CreateMqttHeartThread failed!\n");
                                }
                                break;
                            case 2://0x02 设备失败注册
                                LOGI("Type:2  the dev register failed!\n");
                                break;
                            default:
                                LOGD("Type:xx register Retention extension!\n");
                        }
                    }
                    break;
                /*  设备ID/(是否点播) (eg:000001/0) */
                case RT_VIDEO:
                    if(strcmp(payloadptr0, stInfo.azDeviceId) == 0)
                    {
                        //开启rtsp推流，并且发送直播流地址到服务端
                        switch(atoi(payloadptr1))
                        {
                            case 0://0x00 设备不点播
                               LOGI("Type:0 the dev not rt_video!\n");
                               s32Ret = PLUG_STREAM_Deinit();
                               if (HI_SUCCESS != s32Ret)
                               {
                                   LOGE("PLUG_STREAM_Init failed! %d\n", s32Ret);
                               }
                                break;
                            case 1://0x01 设置点播
                                LOGI("Type:1 the dev rt_video successfully!\n");
                                s32Ret = PLUG_STREAM_Init();
                                if (HI_SUCCESS != s32Ret)
                                {
                                    LOGE("PLUG_STREAM_Init failed! %d\n", s32Ret);
                                }
                                
                                break;

                            default:
                                LOGD("Type:xx rt_video Retention extension!\n");
                        }
                    }
                    break;
                case RT_TALK:
                    if(strcmp(payloadptr0, stInfo.azDeviceId) == 0)
                    {
                        switch(atoi(payloadptr1))
                        {
                            case 0://0x00 设备关闭音频流
                               LOGI("Type:0 the dev stop rt_talk!\n");
                               s32Ret = PLUG_TALK_Deinit();
                               if (HI_SUCCESS != s32Ret)
                               {
                                   LOGE("PLUG_TALK_Deinit failed! %d\n", s32Ret);
                               }
                                break;
                            case 1://0x01 设备开启接受音频流
                                LOGI("Type:0 the dev start rt_talk!\n");
                                
                                HI_CHAR azTalkUrl[512] = {0};
                                set = MQTT_SearchPayloadInfo(payloadptr, '/', 2, azTalkUrl, sizeof(azTalkUrl), HI_TRUE);
                                if(set != HI_SUCCESS)
                                {
                                    LOGE("payloadptr1 analysis error!\n");
                                }
                                
                                LOGI("azTalkUrl:[%s]\n", azTalkUrl);
                                s32Ret = PLUG_TALK_Init(azTalkUrl);
                                if (HI_SUCCESS != s32Ret)
                                {
                                    LOGE("PLUG_TALK_Init failed! %d\n", s32Ret);
                                }
                                break;
                            default:
                                LOGD("Type:xx rt_video Retention extension!\n");
                        }
                    }
                    break;
                default :
                    LOGD("Type:xxxx Retention extension!\n");
            }
        }
    }    
    
    return HI_SUCCESS;
}


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */

